package com.game.service.game.redblack;

import com.game.service.app.Deduction;
import com.game.service.app.FeeOrderReturn;
import com.game.service.app.Utils;
import com.game.service.app.get_score.UserLoginInfo;
import com.game.service.beans.GameConfig;
import com.game.service.beans.UserInfo;
import com.game.service.db.UserScoreDaoImpl;
import com.game.service.game.turntable.GameResult;
import com.game.service.game.turntable.PrizeItem;
import com.game.service.game.turntable.UserBet;
import com.game.service.game.turntable.config.Prize;
import com.game.service.socket.FileUtils;
import com.game.service.socket.SocketServer;
import com.game.service.windows.LogWindows;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.Random;

import static com.game.service.app.Utils.LogDate;
import static com.game.service.app.Utils.random;
import static com.game.service.define.RoomConfig.*;
import static com.game.service.define.RoomConfig.ORDER_PRIZE;

public class RedBlackTable {

    private static final float redOdds = 1.95f;//红色赔率
    private static final float blackOdds = 1.95f;//黑色赔率 ,
    private static final float kill = 0;//抽杀机率(以百为底)kill=2.0,抽杀为2.0%,;(1.95+1.95)/4=97.5%,抽杀设置为2%庄家返奖率下降2%，即95.75%
    private static final int lucky = 100;//标记玩家是否幸运用户百分比,默认100%。(控制玩家新号刷分)
    private static final int roomRatio = 10;//房间倍率
    private static final float protect = 0;//新手保护机率(0~10)
    private static final int protectCounts = 100;//新手保护次数
    public static final int[] betArray = {1, 2, 5, 10, 20, 50, 100, 200, 500, 1000};
    public static final float[] betArrayKill = {0, 0, 0, 0, 0, 0, 0, 0.4f, 1.0f, 2.0f};
    public static final float[] betArrayProtect = {2, 1, 0, 0, 0, 0, 0, -1.2f, -3.0f, -6.0f};

   /* public static void testBet() {
        //一百万局，最大值用1000个钻石打，盈利为三百万
        long money = 1000L * 10000 * 100000;
        isDebug = true;
        UserInfo userInfo = new UserInfo();
        int playCounts = UserScoreDaoImpl.getInstance().getPlayCounts(GAME_ID, 10003);
        userInfo.setPlayCounts(playCounts);
        userInfo.setLuckyValue(random(1, 100));
        SocketServer.getKernel().getUserMap().put(10003, userInfo);

        for (int i = 0; i < 100; i++) {
            int betIndex = random(6, 6);
            int randomBet = getBetNumber(betIndex);
            money -= randomBet;
//            if (money < 0) {
//                System.out.println("输完了第" + i + "," + randomBet);
//                break;
//            }
            UserBet userBet = new UserBet();
            userBet.setUid(10003);
            int red = Utils.random(1, 2);
            userBet.setIsRed(red);
            userBet.setBet(betIndex);

            GameResult gameResult = onTurntableGameResult("game_10005_" + i, new FeeOrderReturn(), userBet);
            money += gameResult.prize;
            //TODO 倍投测试代码
//            if (gameResult.item % 2 == 0) {//下注红色,如果开了黑色则加倍。
//                betIndex++;
//                if (betIndex >= 20) {
//                    System.out.println("达到限高" + i);
//                    System.out.println("最长连续出现正面的次数: " + maxConsecutiveHeads + ",10次正面以上的" + max10);
//                    break;
//                }
//            } else {
//                money += (long) (randomBet * 1.95f);
//                betIndex = 4;
//            }
//            System.out.println("倍投法获得=" + money / 1000 + "," + i + "系统win=" + win / 1000);

            total(gameResult.item);
        }
        for (int i = 0; i < getGameLogs().size(); i++) {
            getGameLogs().get(i).getGameRunInfo();
        }
        System.out.println("最长连续出现正面的次数: " + maxConsecutiveHeads + ",8次正面以上的" + max8 + ",10次正面以上的" + max10 + ",20次正面以上的" + max20);
    }*/


    static boolean isDebug = false;

    //---------------------------以上是测试代码--------------------------------

    private static RedBlackConfig redBlackConfig;//游戏配置

    public static void initGameConfig() {
        GameConfig gameConfig = UserScoreDaoImpl.getInstance().getGameConfig(GAME_ID);
        String dbConfig = null;
        if (gameConfig != null) {
           // dbConfig = gameConfig.getConfig();
        }
        if (dbConfig != null && dbConfig.length() > 2) {
            redBlackConfig = new Gson().fromJson(dbConfig, RedBlackConfig.class);
            String log = String.format("加载数据库-游戏配置:%s", dbConfig);
            FileUtils.writeTxtToFile(log, Utils.LogDate(), LOG_NAME_ROOM);
            LogWindows.getLogWindows().printToTextArea(log, RedBlackTable.class);
        }
        if (redBlackConfig == null) {
            redBlackConfig = new RedBlackConfig();

            redBlackConfig.setRedOdds(redOdds);
            redBlackConfig.setBlackOdds(blackOdds);
            redBlackConfig.setKill(kill);
            redBlackConfig.setLucky(lucky);
            redBlackConfig.setProtect(protect);
            redBlackConfig.setProtectCounts(protectCounts);
            redBlackConfig.setRoomRatio(roomRatio);
            redBlackConfig.setBetArray(betArray);
            redBlackConfig.setBetArrayKill(betArrayKill);
            redBlackConfig.setBetArrayProtect(betArrayProtect);
            String json = new Gson().toJson(redBlackConfig);//添加到数据库使用
            String log = String.format("加载本地-游戏配置:%s", json);
            FileUtils.writeTxtToFile(log, Utils.LogDate(), LOG_NAME_ROOM);
            LogWindows.getLogWindows().printToTextArea(log, RedBlackTable.class);
        }
    }

    public static GameResult onTurntableGameResult(String orderid, FeeOrderReturn feeOrderReturn, UserBet userBet) {
        final int betIndex = userBet.getBet();
        final int betNumber = getBetNumber(betIndex);//获取实际的押注,防止客户端篡改押注
        //玩家游玩次数信息
        UserInfo userInfo = SocketServer.getKernel().getUserMap().get(userBet.getUid());
        boolean betRed = userBet.getIsRed() % 2 == 1;

        boolean isNewPlayer = userInfo.getPlayCounts() < getConfig().getProtectCounts();
        boolean isLuckyPlayer = userInfo.getLuckyValue() > 100 - getConfig().getLucky();

        // int item;//中奖项
        PrizeItem item;
        if (isNewPlayer && isLuckyPlayer) {//如果是新手玩家并且是幸运用户,则使用新手玩家的保护机制。

            int randomProtect = random(1, 1000);
            float protect = getConfig().getProtect();//基础保护机率
            float betProtect = getBetArrayProtect(userBet.getBet());//动态保护机率
            float protectTotal = (protect + betProtect) * 10;//百分比 ,一位精确值
            if (randomProtect <= protectTotal) {//最终保护机率=基础保护机率+动态保护
                item = openPrize(betRed ? 1 : 2);
                item.setItemStatus(2);
            } else {
                item = openPrize(random(1, 2));
                item.setItemStatus(0);
            }

        } else {//过了新手保护期,优先判断抽杀

            int randomKill = random(1, 1000);
            float kill = getConfig().getKill();
            float betKill = getBetArrayKill(userBet.getBet());
            float killTotal = (kill + betKill) * 10;//百分比 ,一位精确值
            if (randomKill <= killTotal) {//一旦抽杀,则反着开
                item = openPrize(betRed ? 2 : 1);
                item.setItemStatus(1);

            } else {
                item = openPrize(random(1, 2));
                item.setItemStatus(0);
            }
        }

        userInfo.setPlayCountsAdd();//记录玩家游戏次数
        // userInfo.getPrize().add(betIndex, item);//新增玩家游玩信息记录表prize  红黑暂时不接入奖励系统
        long score = feeOrderReturn.getScore();
        GameResult gameResult = new GameResult();
        gameResult.orderid = orderid;
        gameResult.score = score;
        gameResult.item = item.getPos();
        gameResult.betid = betIndex;//新增记录下注id 对应betArray[]
        gameResult.prizeid = item.getId();//返奖id 对应tableItems[]
        gameResult.ratio = "x" + item.getRate();
        gameResult.fee = betNumber;
        gameResult.prize = item.getId() == userBet.getIsRed() ? (int) (item.getRate() * betNumber) : 0;
        gameResult.deduction = feeOrderReturn.getDeduction();//本次玩家扣除内容
        gameResult.isRed = userBet.getIsRed();
        gameResult.itemStatus = item.getItemStatus();
        userInfo.setScore(score + gameResult.prize);//记录玩家当前分数

        return gameResult;


    }

    public static int getBetNumber(int betIndex) {

        int[] betArray = getConfig().getBetArray();
        if (betIndex < betArray.length) {
            return betArray[betIndex] * getConfig().getRoomRatio();
        }
        return 0;
    }

    public static void initGameConfigNet(RedBlackConfig redBlackConfigNet) {
        redBlackConfig = redBlackConfigNet;
        FileUtils.writeTxtToFile("加载总服务器-游戏配置" + redBlackConfig, Utils.LogDate(), LOG_NAME_ROOM);
    }

    public static synchronized RedBlackConfig getConfig() {
        if (redBlackConfig == null) {
            initGameConfig();
        }
        return redBlackConfig;
    }

    public static float getRebate() {
        return (redBlackConfig.getRedOdds() + redBlackConfig.getBlackOdds()) / 4;
    }

    public static float getBetArrayKill(int betIndex) {

        if (betIndex >= 0 && betIndex < getConfig().getBetArrayKill().length) {
            return getConfig().getBetArrayKill()[betIndex];
        }
        return 0;
    }

    public static float getBetArrayProtect(int betIndex) {

        if (betIndex >= 0 && betIndex < getConfig().getBetArrayProtect().length) {
            return getConfig().getBetArrayProtect()[betIndex];
        }
        return 0;
    }

    /***
     *
     * @param openPos 1表示红色，2表示黑色
     * @return 中奖项
     */
    public static PrizeItem openPrize(int openPos) {
        PrizeItem prizeItem = new PrizeItem();
        prizeItem.setId(openPos);//1表示红色，2表示黑色
        prizeItem.setPos(openPos);
        float odds = openPos == 1 ? getConfig().getRedOdds() : getConfig().getBlackOdds();
        prizeItem.setRate(odds);
        return prizeItem;
    }


    private static long tableIdIndex = 100000000;//游戏场次ID
    public static long mDiamondMax = 0;
    public static long mBetIndex = 0;

    /***
     *
     * @return  "game_GAME_ID_时间_";
     */
    private static String orderIdHead() {
        tableIdIndex++;
        return "game_" + GAME_ID + "_" + Utils.getDateTableId() + "_";
    }

    public static void testBet() {
        isDebug = true;
        int uid = 10089;
        int playCounts = UserScoreDaoImpl.getInstance().getPlayCounts(GAME_ID, uid);
        UserInfo userInfo = new UserInfo();
        userInfo.setUid(uid);
        userInfo.setMac("token");
        userInfo.setPlayCounts(playCounts);
        userInfo.setLuckyValue(random(1, 100));
        userInfo.setUserLoginInfo(new UserLoginInfo());
        Prize prize = new Prize();
        prize.loadDb(GAME_ID, uid, betArray);
        userInfo.setPrize(prize);
        SocketServer.getKernel().getUserMap().put(uid, userInfo);
        //
        FeeOrderReturn feeOrderReturn = new FeeOrderReturn();
        feeOrderReturn.setCoin(1000);
        feeOrderReturn.setScore(100000);
        feeOrderReturn.setDeduction(new Deduction());

        long mDiamond = 2000000;
        for (int i = 0; i < 100; i++) {
            int betIndex = random(0,0);
            mDiamond -= (long) betArray[betIndex] * roomRatio;
            UserBet userBet = new UserBet();
            userBet.setUid(uid);
            userBet.setToken("token");
            userBet.setLiveid(-999);
            userBet.setStream("-9999_-9999");
            userBet.setBet(betIndex);
            userBet.setIsRed(1);//红色

            String orderIdHead = orderIdHead();
            userBet.setOrderIdFee(orderIdHead + ORDER_FEE + tableIdIndex);
            userBet.setOrderIdPrize(orderIdHead + ORDER_PRIZE + tableIdIndex);
            userBet.setTableType(1);

            SocketServer.getKernel().feeOrderSuccess(null, userBet, feeOrderReturn);
//            GameResult gameResult = onTurntableGameResult(userBet.getOrderIdPrize(), mDiamond, userBet);

            //  mDiamond += gameResult.prize;
            //  System.out.println(mDiamond + "");
            if (mDiamond < 0) {
                System.out.println("输完了,第" + i + "把");
                break;
            }
            if (mDiamond > mDiamondMax) {
                mDiamondMax = mDiamond;
                mBetIndex = i;
            }
        }


    }

}
